package com.iwhalecloud.bss.kite.cucc.order.util;

import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.constant.ServiceOfferConsts;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.dataservice.entity.OrderItem;
import com.iwhalecloud.bss.kite.dataservice.entity.inst.OfferObjInstRel;
import com.iwhalecloud.bss.kite.order.client.dto.InstContainer;
import com.iwhalecloud.bss.kite.order.client.dto.OrderContainer;
import com.iwhalecloud.bss.kite.order.client.dto.OrderRequest;
import com.ztesoft.bss.order.base.consts.KeyValues;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * <Description> <br>
 * 订单项同笔订单标识处理辅助工具类
 *
 * @author xiao.xuzhang<br>
 * @version 1.0<br>
 * @taskId <br>
 * @CreateDate 2020年3月5日 <br>
 * @since R9.0<br>
 * @see com.iwhalecloud.bss.kite.cucc.order.util <br>
 */
public abstract class AskIdUtils {

    /**
     * Description: <br>
     * 处理订单项同笔订单标识
     *
     * @taskId <br>
     * @param orderRequest <br>
     */
    public static void dealAskId(OrderRequest orderRequest) {
        // 设置基础销售品订单askId
        setBaseOfferOrderItemAskId(orderRequest);

        // 派生单askId设置主订单项ID(TODO)

        // 退订单askId设置新购单订单ID(TODO)

        // 设置askId必须为主流销售品订单ID
        setMainOrderItemAskId(orderRequest);
    }

    /**
     * Description: <br>
     * 根据askId分组
     *
     * @return <br>
     */
    public static Map<String, List<OrderItem>> orderItemGroupByAskId(List<OrderItem> orderItems) {
        Map<String, List<OrderItem>> orderItemMap = new HashMap<String, List<OrderItem>>();
        for (OrderItem orderItem : orderItems) {
            orderItemMap.computeIfAbsent(orderItem.getAskId(), key -> new ArrayList<OrderItem>()).add(orderItem);
        }

        return orderItemMap;
    }

    /**
     * Description: <br>
     * 设置基础销售品订单的同笔订单标识<br>
     * 找到基础销售品实例所在的主套餐或者促销套餐订单项ID作为此基础销售品AskId
     *
     * @param orderRequest <br>
     */
    public static void setBaseOfferOrderItemAskId(OrderRequest orderRequest) {
        // 获取基础销售品订单集合
        List<OrderItem> baseOfferOrderItems = OrderContainer.ofRequest(orderRequest)
            .listOrderItemsByOfferType(KeyConsts.OFFER_TYPE_10);

        List<OrderItem> allOrderItems = OrderContainer.ofRequest(orderRequest).listOrderItems();
        for (OrderItem baseOfferOrderItem : baseOfferOrderItems) {
            for (OrderItem orderItem : allOrderItems) {
                // 相同订单项不处理
                if (KiteStringUtils.isEqual(baseOfferOrderItem.getOrderItemId(), orderItem.getOrderItemId())) {
                    continue;
                }

                // 不是主套餐或者促销套餐订单不处理
                if (!isOfferOrProOffer(orderItem)) {
                    continue;
                }

                // 判定是否存在套餐明细实例关系
                if (!isContainRela(baseOfferOrderItem, orderItem, orderRequest)) {
                    continue;
                }

                // 符合条件，设置基础销售品askId
                baseOfferOrderItem.setAskId(orderItem.getAskId());

                if (KeyConsts.OFFER_TYPE_11.equals(orderItem.getOfferKind())) {
                    break;
                }
            }
        }
    }

    /**
     * Description: <br>
     * 设置askId必须为主流销售品的order_item_id
     *
     * @taskId <br>
     * @param orderRequest <br>
     */
    public static void setMainOrderItemAskId(OrderRequest orderRequest) {
        Map<String, List<OrderItem>> orderItemMap = orderItemGroupByAskId(
            OrderContainer.ofRequest(orderRequest).listOrderItems());

        // 记录主流套餐订单askId与orderItemId不一致订单项集合
        List<OrderItem> mianOrderItems = new ArrayList<>();
        for (Entry<String, List<OrderItem>> entry : orderItemMap.entrySet()) {
            String askId = entry.getKey();
            List<OrderItem> orderItems = entry.getValue();
            mianOrderItems.addAll(listNoMatchOrderItems(askId, orderItems));
        }

        if (KiteListUtils.isEmpty(mianOrderItems)) {
            return;
        }

        // 设置主流套餐订单askId为自身orderItemId,同时变更askId下订单集合
        for (OrderItem orderItem : mianOrderItems) {
            String askId = orderItem.getAskId();
            String orderItemId = orderItem.getOrderItemId();
            List<OrderItem> sameAskIdOrderItems = OrderContainer.ofRequest(orderRequest).listOrderItemsByAskId(askId);
            orderItem.setAskId(orderItemId);

            for (OrderItem subOrderItem : sameAskIdOrderItems) {
                subOrderItem.setAskId(orderItemId);
            }
        }
    }

    /**
     * Description: <br>
     * 获取主流套餐订单项askId与orderItemId不一致情况
     *
     * @taskId <br>
     * @param askId
     * @param orderItems <br>
     */
    public static List<OrderItem> listNoMatchOrderItems(String askId, List<OrderItem> orderItems) {
        List<OrderItem> noMatchorderItems = new ArrayList<>();
        for (OrderItem orderItem : orderItems) {
            // 销售品退订服务不处理
            if (KiteStringUtils.isEqual(orderItem.getServiceOfferId(), ServiceOfferConsts.SERVICE_OFFER_CANCEL)) {
                continue;
            }

            // 非主套餐不处理
            if (!KiteStringUtils.isEqual(orderItem.getOfferKind(), KeyConsts.OFFER_TYPE_11)) {
                continue;
            }

            if (!KiteStringUtils.isEqual(orderItem.getOrderItemId(), askId)) {
                noMatchorderItems.add(orderItem);
            }
        }

        return noMatchorderItems;
    }

    /**
     * 是否套餐销售品或促销销售品
     *
     * @return
     */
    public static Boolean isOfferOrProOffer(OrderItem orderItem) {
        if (KiteStringUtils.equalsAny(orderItem.getOfferKind(), KeyValues.OFFER_KIND_1, KeyValues.OFFER_KIND_3)) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    /**
     * Description: <br>
     * 判定A订单项对应实例与B订单项对应实例存在销售品产品关系<br>
     * 即A订单项作为基础销售品订单，B订单项作为主套餐或者促销套餐订单，A订单对应基础销售品实例作为成员加入B订单对应的套餐实例
     *
     * @taskId <br>
     * @param aOrderItem
     * @param bOrderItem
     * @param orderRequest
     * @return <br>
     */
    public static Boolean isContainRela(OrderItem aOrderItem, OrderItem bOrderItem, OrderRequest orderRequest) {
        String aCompInstId = aOrderItem.getObjId();
        String bCompInstId = bOrderItem.getObjId();

        // 获取基础销售品实例

        Map<String, OfferObjInstRel> offerDetailInstMap = InstContainer.ofRequest(orderRequest)
            .getOfferObjInstRelMap(bCompInstId);
        return offerDetailInstMap.values().stream()
            .anyMatch(p -> KiteStringUtils.isEqual(p.getMcompInstId(), aCompInstId));

    }

}
